#pragma once
#include<iostream>
#include<queue>
#include<mutex>
#include<pthread.h>

template<class T>
class BlockQueue
{
    static const int defaultNum=20;
public:
    BlockQueue(int maxCapacity=defaultNum)
        :_maxCapacity(maxCapacity)
    {
        pthread_mutex_init(&mtx,nullptr);
        pthread_cond_init(&p_cond,nullptr);
        pthread_cond_init(&c_cond,nullptr);
    }

    T Pop()
    {
        pthread_mutex_lock(&mtx);
        //当队列为空时阻塞
        while(_q.size()==0) //因为判断临界资源调试是否满足，也是访问临界资源，判断资源是否就绪，是通过资源内部判断的
        {
            //如果线程wait时，被唤醒误了，也不怕，因为你是持有锁的，自动释放锁，因为唤醒而返回的时候，会重新持有锁。
            pthread_cond_wait(&c_cond,&mtx);
        }
        // T*out=_q.top();
        T out=_q.front();
        _q.pop();
        pthread_cond_signal(&p_cond);
        pthread_mutex_unlock(&mtx);
        return out;
    }

    void Push(const T&in)
    {
        pthread_mutex_lock(&mtx);
        //当队列为满的时候，阻塞
        while(_q.size()==_maxCapacity)
        {
            pthread_cond_wait(&p_cond,&mtx);
        }
        _q.push(in);
        pthread_cond_signal(&c_cond);
        pthread_mutex_unlock(&mtx);
    }

    ~BlockQueue()
    {
        pthread_mutex_destroy(&mtx);
        pthread_cond_destroy(&p_cond);
        pthread_cond_destroy(&c_cond);
    }
private:
    std::queue<T> _q;
    int _maxCapacity;//最值
    pthread_mutex_t mtx;
    pthread_cond_t p_cond;
    pthread_cond_t c_cond;    
};